﻿
using System;

class SlkAction : SlkTree
{

    internal
    SlkAction(SlkToken scanner)
        : base()
    {
        this.scanner = scanner;
        semantic_stack = new Stack();
        answer = 0;
    }

    private SlkToken scanner;
    private double answer;
    private Stack semantic_stack;

    public double get_answer() { return answer; }
    public void state(int number) { }

    // -----------------------------------------------------------------------
    // grammar action code functions
    // -----------------------------------------------------------------------

    private
    void
    Add()
    {
        double op;

        answer = semantic_stack.pop();
        op = semantic_stack.pop();
        if (op == '+')
        {
            answer = semantic_stack.pop() + answer;
        }
        else
        {
            answer = semantic_stack.pop() - answer;
        }
        semantic_stack.push(answer);
    }

    private
    void
    Finish()
    {
        answer = semantic_stack.pop();
    }

    private
    void
    Multiply()
    {
        double op;

        answer = semantic_stack.pop();
        op = semantic_stack.pop();
        if (op == '*')
        {
            answer = semantic_stack.pop() * answer;
        }
        else
        {
            answer = semantic_stack.pop() / answer;
        }
        semantic_stack.push(answer);
    }

    private
    void
    Exponent()
    {
        answer = semantic_stack.pop();
        answer = Math.Pow(semantic_stack.pop(), answer);
        semantic_stack.push(answer);
    }

    private
    void
    Negate()
    {
        answer = semantic_stack.pop();
        semantic_stack.push(-answer);
    }

    private
    void
    Push()
    {
        semantic_stack.push(scanner.get_attribute());
    }

    public void execute(int number)
    {
        switch (number)
        {
            case 1: Finish(); break;
            case 2: Add(); break;
            case 3: Push(); break;
            case 4: Multiply(); break;
            case 5: Exponent(); break;
            case 6: Negate(); break;
        }
    }

};
